#ifndef __DEFAULTS__
#define __DEFAULTS__

#include <iostream>
#include <fstream>
#include <sstream>

#include <vector>
#include <list>
#include <map>
#include <set>

#include <string>
#include <limits>
#include <cassert>
#include <cmath>
#include <algorithm>

#include <math.h>
#include <time.h>

#include <GL/glew.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/vector_proxy.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/triangular.hpp>
#include <boost/numeric/ublas/storage.hpp>
#include <boost/tuple/tuple.hpp>

#include <boost/multi_array.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/lu.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/array.hpp>

#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/progress.hpp>
#include <boost/variant.hpp>
#include <boost/math/constants/constants.hpp>

#include "math/vector.h"
#include "math/matrix.h"

typedef double nfloat;
typedef math::Vec<nfloat, 1> Vec1n;
typedef math::Vec<nfloat, 2> Vec2n;
typedef math::Vec<nfloat, 3> Vec3n;
typedef math::Vec<nfloat, 4> Vec4n;
typedef math::Vec<nfloat, 5> Vec5n;
typedef math::Vec<nfloat, 6> Vec6n;
typedef math::Vec<nfloat, 7> Vec7n;
typedef math::Vec<nfloat, 9> Vec9n;
typedef math::Vec<nfloat, 10> Vec10n;
typedef math::Vec<nfloat, 13> Vec13n;
typedef math::Vec<nfloat, 15> Vec15n;
typedef math::Mat4x4<nfloat> Mat4x4n;

typedef boost::numeric::ublas::matrix<nfloat> Matrix;
typedef boost::numeric::ublas::zero_matrix<nfloat> ZeroMatrix;
typedef boost::numeric::ublas::mapped_matrix<nfloat> SparseMatrix;
typedef boost::numeric::ublas::vector<nfloat, std::vector<nfloat> > Vector;
typedef boost::numeric::ublas::zero_vector<nfloat> ZeroVector;
typedef boost::numeric::ublas::identity_matrix<nfloat> IdentityMatrix;
typedef boost::multi_array<Vec3n, 3> Array3V3n;
typedef boost::multi_array<Vec4n, 3> Array3V4n;
typedef boost::multi_array<Vec2n, 2> Array2V2n;
typedef boost::multi_array<Vec3n, 2> Array2V3n;
typedef boost::multi_array<Vec4n, 2> Array2V4n;
typedef boost::multi_array<nfloat, 2> Array2;

extern std::string GetPath(const std::string& file);

#define PRINTVAR(x) std::cout << #x << "=" << x << std::endl
#define PRINTVAR2(x1, x2) std::cout << #x1 << "=" << x1 << " " << #x2 << "=" << x2 << std::endl
#define PRINTVAR3(x1, x2, x3) std::cout << #x1 << "=" << x1 << " " << #x2 << "=" << x2 << " " << #x3 << "=" << x3 << std::endl
#define PRINTVAR4(x1, x2, x3, x4) std::cout << #x1 << "=" << x1 << " " << #x2 << "=" << x2 << " " << #x3 << "=" << x3 <<  " " << #x4 << "=" << x4 <<std::endl
#define PRINTVAR5(x1, x2, x3, x4, x5) std::cout << #x1 << "=" << x1 << " " << #x2 << "=" << x2 << " " << #x3 << "=" << x3 <<  " " << #x4 << "=" << x4 << " " << #x5 << "=" << x5 << std::endl
#define PRINTVAR6(x1, x2, x3, x4, x5, x6) std::cout << #x1 << "=" << x1 << " " << #x2 << "=" << x2 << " " << #x3 << "=" << x3 <<  " " << #x4 << "=" << x4 << " " << #x5 << "=" << x5 << " " << #x6 << "=" << x6 << std::endl
#define PRINTVAR7(x1, x2, x3, x4, x5, x6, x7) std::cout << #x1 << "=" << x1 << " " << #x2 << "=" << x2 << " " << #x3 << "=" << x3 <<  " " << #x4 << "=" << x4 << " " << #x5 << "=" << x5 << " " << #x6 << "=" << x6 << " " << #x7 << "=" << x7 << std::endl
#define PRINTVAR8(x1, x2, x3, x4, x5, x6, x7, x8) std::cout << #x1 << "=" << x1 << " " << #x2 << "=" << x2 << " " << #x3 << "=" << x3 <<  " " << #x4 << "=" << x4 << " " << #x5 << "=" << x5 << " " << #x6 << "=" << x6 << " " << #x7 << "=" << x7 << " " << #x8 << "=" << x8 << std::endl

#endif //__DEFAULTS__
